#pragma once 

#include <vector>
#include <set>
#include <shared_mutex>
#include <boost/circular_buffer.hpp>
#include "media_source.hpp"
#include "base/sequence_pkt_buf.hpp"


namespace mms{
class ThreadWorker;
class RtmpMediaSink;
class StreamSession;
class RtmpMessage;
class MediaSink;
class RtmpMetaDataMessage;

class RtmpMediaSource: public MediaSource{
public:
    RtmpMediaSource(ThreadWorker *worker, std::weak_ptr<StreamSession> s);
    virtual ~RtmpMediaSource();

    bool init();
    bool on_audio_packet(std::shared_ptr<RtmpMessage> &audio_pkt);
    bool on_video_packet(std::shared_ptr<RtmpMessage> &video_pkt);
    bool on_metadata(std::shared_ptr<RtmpMessage> metadata_pkt);

    std::vector<std::shared_ptr<RtmpMessage>> get_pkts(int64_t &last_pkt_index, uint32_t max_count);
    virtual bool add_media_sink(std::shared_ptr<MediaSink> media_sink);
    void close();

    std::shared_ptr<MediaBridge> get_or_create_bridge(const std::string& id, StreamSession* session) override;

protected:
    SequencePktBuf<RtmpMessage> av_pkts_;
    std::shared_ptr<RtmpMetaDataMessage> metadata_;
    std::shared_ptr<RtmpMessage> video_header_;
    std::shared_ptr<RtmpMessage> audio_header_;

    std::shared_mutex keyframe_indexes_rw_mutex_;
    boost::circular_buffer<uint64_t> keyframe_indexes_;
    int64_t latest_frame_index_ = 0;

    bool video_ready_ = false;
    bool audio_ready_ = false;
    int32_t latest_video_timestamp_ = 0;
    int32_t latest_audio_timestamp_ = 0;


    int32_t video_key_ind = -1;
    int32_t last_key_ind = 0;
};


}